const PROMISE_STATUS_PENDING = "PROMISE_STATUS_PENDING";
const PROMISE_STATUS_FULFTLLED = "PROMISE_STATUS_FULFTLLED";
const PROMISE_STATUS_REJECTED = "PROMISE_STATUS_REJECTED";

function withCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value);
    resolve(result);
  } catch (error) {
    reject(error);
  }
}

class YYpromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING;
    this.onfullfiled = [];
    this.onrejected = [];
    this.value = null;
    this.reason = null;
    const resolve = (value) => {
      this.value = value;
      if (this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_FULFTLLED;
        queueMicrotask(() => {
          this.onfullfiled.forEach((fn) => fn(value));
        });
      }
    };
    const reject = (reason) => {
      this.reason = reason;
      if (this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_REJECTED;
        queueMicrotask(() => {
          this.onrejected.forEach((fn) => fn(reason));
        });
      }
    };
    executor(resolve, reject);
  }

  then = (onfullfiled, onrejected) => {
    onfullfiled=onfullfiled||(e=>e)
    onrejected=onrejected||(err=>{throw err})
    return new YYpromise((resolve, reject) => {
      if (this.status === PROMISE_STATUS_FULFTLLED) {
        withCatchError(onfullfiled, this.value, resolve, reject);
      }
      if (this.status === PROMISE_STATUS_REJECTED) {
        withCatchError(onrejected, this.reason, resolve, reject);
      }
      if (this.status === PROMISE_STATUS_PENDING) {
        this.onfullfiled.push(() => {
          withCatchError(onfullfiled, this.value, resolve, reject);
        });
        this.onrejected.push(() => {
          withCatchError(onfullfiled, this.reason, resolve, reject);
        });
      }
    });
  };
  catch(err) {
    return this.then(undefined, err);
  }
  finally(callback){
    this.then(callback,callback)
  }
   all =(promises)=>{
    const result=[]
    return new YYpromise((resolve,reject)=>{
      for (const promise of promises) {
        promise.then(res=>{
          result.push(res)
          if (result.length===promises.length) {
            resolve(result)
          }
        },err=>{
          reject(err)
        })
      }
    })
  }

   allSeleted=(promises)=>{
    const result=[]
    return new YYpromise((resolve,reject)=>{
      for (const promise of promises) {
        promise.then(res=>{
          result.push({status:PROMISE_STATUS_FULFTLLED,value:res})
          if (result.length===promises.length) {
            resolve(result)
          }
        },err=>{
          result.push({status:PROMISE_STATUS_REJECTED,value:err})
          if (result.length===promises.length) {
            resolve(result)
          }
        })
      }
    })
  }

  race=(promises)=>{
    return new YYpromise((resolve,reject)=>{
      for (const promise of promises) {
        promise.then(resolve,reject)
      }
    })
  }
}

var p = new YYpromise((resolve, reject) => {
  // reject("123");
  resolve(123);
});
// 执行。then 就会去执行 resolve 然后回调
p.then(
  (res) => {
    console.log("res1:", res);
    throw 1213;
  }
).catch((err) => {
  console.log(err);
});
